package com.sychip.fhc.app.wsn.screen


import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.fhc.view.NameValueDto
import com.sychip.fhc.AppType
import com.sychip.fhc.app.data.repo.TaskRepo
import com.sychip.fhc.app.pref.AppSetting
import com.sychip.fhc.app.pref.PrefDataStoreIf
import com.sychip.fhc.app.todo.R
import com.sychip.fhc.app.todo.TodoDestinationsArgs
import com.sychip.fhc.app.wsn.nav.WsnUsbStatus
import com.sychip.fhc.base.CommonUiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * UiState for the Add/Edit screen
 */
data class SettingUiState(
    val title: String = "",
    val description: String = "",
    val isTaskCompleted: Boolean = false,
    val isLoading: Boolean = false,
    val userMessage: Int? = null,
    val isTaskSaved: Boolean = false,
)


data class WsnSettingDto(
    var title: String = "",
    var description: String = "",
    val selectedItem: NameValueDto = NameValueDto("",""),
    val appSetting: AppSetting = AppSetting(appType = AppType.Todo)
)


/**
 * ViewModel for the Add/Edit screen.
 */
@HiltViewModel
class WsnSettingViewModel @Inject constructor(
    private val taskRepository: TaskRepo,
    private val prefDataStore: PrefDataStoreIf,
    savedStateHandle: SavedStateHandle
) : ViewModel() {
    private val _usbFlow = MutableStateFlow<WsnUsbStatus>(WsnUsbStatus())
    val usbFlow: StateFlow<WsnUsbStatus> = _usbFlow.asStateFlow()



    init {
        prefDataStore.getUsbDevice().map { result ->
            _usbFlow.update { WsnUsbStatus(isNew = false, usb = result) }
        }.launchIn(viewModelScope)
    }

    private val taskId: String? = savedStateHandle[TodoDestinationsArgs.TASK_ID_ARG]

    // A MutableStateFlow needs to be created in this ViewModel. The source of truth of the current
    // editable Task is the ViewModel, we need to mutate the UI state directly in methods such as
    // `updateTitle` or `updateDescription`
    private val _uiState = MutableStateFlow(SettingUiState())
    val uiState: StateFlow<SettingUiState> = _uiState.asStateFlow()

//    mutableStateOf包装的是WsnSettingDto对象引用，而非其内部属性24
//    修改对象属性不会改变对象引用，Compose无法感知变化
//    必须创建新对象引用（通过copy()或重新赋值）2
//    对于表单场景建议采用方案2的分离状态管理4
//    val titleState = remember { mutableStateOf("") }
//    val descState = remember { mutableStateOf("") }

    private val _settingFlow = MutableStateFlow<CommonUiState<WsnSettingDto>>(CommonUiState(dataList = listOf(WsnSettingDto())))
//    private val _setting: MutableState<WsnSettingDto> =  mutableStateOf(WsnSettingDto())
    val settingFlow: StateFlow<CommonUiState<WsnSettingDto>> = _settingFlow.asStateFlow()

    init {
        prefDataStore.getAppSettings().map { result ->
           val aa = _settingFlow.value.dataList[0].copy(appSetting = result)
            _settingFlow.update {
                it.copy(dataList = listOf(aa))
            }
        }.launchIn(viewModelScope)

//        viewModelScope.launch {
//            _appSetting.value.appType = AppType.WSN
//            prefDataStore.saveAppSettings(_appSetting.value)
//        }
//        prefDataStore.getAppSettings().map { result ->
//            _appSetting.value = result
//        }.launchIn(viewModelScope)

        if (taskId != null) {
            loadTask(taskId)
        }

//        if(_setting.value == null){
//
//        }
    }



    fun saveSetting() {
        if (uiState.value.title.isEmpty() || uiState.value.description.isEmpty()) {
            _uiState.update {
                it.copy(userMessage = R.string.empty_task_message)
            }
            return
        }

        if (taskId == null) {
            createNewTask()
        } else {
            updateTask()
        }
    }

    fun snackbarMessageShown() {
        _uiState.update {
            it.copy(userMessage = null)
        }
    }

    fun updateSetting(dto: WsnSettingDto) {
        _settingFlow.update {
            it.copy(dataList = listOf(dto))
        }
    }
    fun updateTitle(title: String) {
        val aa = _settingFlow.value.dataList[0].copy(title = title)
        _settingFlow.update {
            it.copy(dataList = listOf(aa))
        }
    }



    fun updateDescription(newDescription: String) {
        _uiState.update {
            it.copy(description = newDescription)
        }
    }

    private fun createNewTask() = viewModelScope.launch {
        taskRepository.createTask(uiState.value.title, uiState.value.description)
        _uiState.update {
            it.copy(isTaskSaved = true)
        }
    }

    private fun updateTask() {
        if (taskId == null) {
            throw RuntimeException("updateTask() was called but task is new.")
        }
        viewModelScope.launch {
            taskRepository.updateTask(
                taskId,
                title = uiState.value.title,
                description = uiState.value.description,
            )
            _uiState.update {
                it.copy(isTaskSaved = true)
            }
        }
    }

    private fun loadTask(taskId: String) {
        _uiState.update {
            it.copy(isLoading = true)
        }
        viewModelScope.launch {
            taskRepository.getTask(taskId).let { task ->
                if (task != null) {
                    _uiState.update {
                        it.copy(
                            title = task.title,
                            description = task.description,
                            isTaskCompleted = task.isCompleted,
                            isLoading = false
                        )
                    }
                } else {
                    _uiState.update {
                        it.copy(isLoading = false)
                    }
                }
            }
        }
    }
}

